<template>
  <div class="chat-main">
    <div class="chat-history" ref="chatHistoryRef">
      <div
        v-for="(msg, index) in chatHistory"
        :key="index"
        :class="['message', msg.role === 'user' ? 'user-message' : 'assistant-message']"
      >
        <div class="message-content">
          <div v-if="msg.role === 'assistant'" class="assistant-content">
            <!-- 使用 marked-content class 包装 markdown 内容 -->
            <div class="marked-content" v-html="md.render(msg.content || '')" :key="msg.content"></div>
            <div class="typing-indicator" v-if="isLastMessage(index) && isLoading">
              <span></span>
              <span></span>
              <span></span>
            </div>
          </div>
          <div v-else class="marked-content" v-html="md.render(msg.content || '')"></div>

          <div v-if="msg.sources && msg.sources.length > 0" class="message-sources">
            <div class="sources-title">参考文档：</div>
            <ul class="sources-list">
              <li v-for="source in msg.sources" :key="source.id">
                {{ source.title }}
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>

    <div class="chat-input">
      <el-input
        v-model="message"
        placeholder="输入消息..."
        :disabled="disabled || isLoading"
        @keyup.enter="handleSend"
      >
      </el-input>
      <el-button
        type="primary"
        @click="handleSend"
        :disabled="disabled || !message.trim() || isLoading"
      >
        发送
      </el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, watch } from 'vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js/lib/core'
import 'highlight.js/lib/languages/javascript'
import 'highlight.js/lib/languages/python'
import 'highlight.js/lib/languages/typescript'
import 'highlight.js/lib/languages/bash'
import 'highlight.js/lib/languages/json'
import 'highlight.js/lib/languages/xml'
import 'highlight.js/lib/languages/css'
import 'highlight.js/lib/languages/markdown'
import 'highlight.js/lib/languages/sql'
import 'highlight.js/lib/languages/r'
import 'highlight.js/lib/languages/go'
import 'highlight.js/lib/languages/rust'
import 'highlight.js/lib/languages/swift'
import 'highlight.js/lib/languages/kotlin'
import 'highlight.js/lib/languages/java'
import 'highlight.js/lib/languages/php'
import 'highlight.js/lib/languages/ruby'
import 'highlight.js/lib/languages/scala'
import 'highlight.js/lib/languages/shell'
import 'highlight.js/lib/languages/yaml'
import 'highlight.js/styles/github-dark.css'

// 注册代码高亮语言
hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
hljs.registerLanguage('python', require('highlight.js/lib/languages/python'))
hljs.registerLanguage('typescript', require('highlight.js/lib/languages/typescript'))
hljs.registerLanguage('bash', require('highlight.js/lib/languages/bash'))
hljs.registerLanguage('json', require('highlight.js/lib/languages/json'))
hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('css', require('highlight.js/lib/languages/css'))
hljs.registerLanguage('markdown', require('highlight.js/lib/languages/markdown'))
hljs.registerLanguage('sql', require('highlight.js/lib/languages/sql'))
hljs.registerLanguage('r', require('highlight.js/lib/languages/r'))
hljs.registerLanguage('go', require('highlight.js/lib/languages/go'))
hljs.registerLanguage('rust', require('highlight.js/lib/languages/rust'))
hljs.registerLanguage('swift', require('highlight.js/lib/languages/swift'))
hljs.registerLanguage('kotlin', require('highlight.js/lib/languages/kotlin'))
hljs.registerLanguage('java', require('highlight.js/lib/languages/java'))
hljs.registerLanguage('php', require('highlight.js/lib/languages/php'))
hljs.registerLanguage('ruby', require('highlight.js/lib/languages/ruby'))
hljs.registerLanguage('scala', require('highlight.js/lib/languages/scala'))
hljs.registerLanguage('shell', require('highlight.js/lib/languages/shell'))
hljs.registerLanguage('yaml', require('highlight.js/lib/languages/yaml'))

// 配置 markdown-it 与代码高亮
const md = new MarkdownIt({
    html: true,
    breaks: true,
    linkify: true,
    highlight: function (str, lang) {
        // 尝试检测语言，如果没有指定语言，使用自动检测
        if (lang) {
            const language = hljs.getLanguage(lang);
            if (language) {
                try {
                    return `<div class="code-block">
                              <div class="code-header">
                                <span class="code-lang">${lang}</span>
                              </div>
                              <div class="hljs">
                                <code>${hljs.highlight(str, { language: lang }).value}</code>
                              </div>
                            </div>`;
                } catch (error) {
                    console.error('Highlight error:', error);
                }
            }
        }

        // 如果语言未指定或无法识别，尝试自动检测
        try {
            const detectedLanguage = hljs.highlightAuto(str);
            return `<div class="code-block">
                      <div class="code-header">
                        <span class="code-lang">${detectedLanguage.language || 'text'}</span>
                      </div>
                      <div class="hljs">
                        <code>${detectedLanguage.value}</code>
                      </div>
                    </div>`;
        } catch (error) {
            // 如果自动检测失败，返回转义的 HTML
            return `<div class="code-block">
                      <div class="code-header">
                        <span class="code-lang">text</span>
                      </div>
                      <div class="hljs">
                        <code>${md.utils.escapeHtml(str)}</code>
                      </div>
                    </div>`;
        }
    }
})
const props = defineProps({
  chatHistory: {
    type: Array,
    required: true
  },
  isLoading: {
    type: Boolean,
    default: false
  },
  disabled: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['send'])

const message = ref('')
const chatHistoryRef = ref(null)

const scrollToBottom = () => {
  nextTick(() => {
    if (chatHistoryRef.value) {
      chatHistoryRef.value.scrollTop = chatHistoryRef.value.scrollHeight
    }
  })
}

const handleSend = () => {
  if (!message.value.trim() || props.disabled || props.isLoading) return
  emit('send', message.value)
  message.value = ''
}

const isLastMessage = (index) => {
  return index === props.chatHistory.length - 1
}

watch(() => props.chatHistory, () => {
  scrollToBottom()
}, { deep: true })

watch(() => props.isLoading, () => {
  scrollToBottom()
})

onMounted(() => {
  scrollToBottom()
})
</script>

<style scoped>
.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.chat-history {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

.message {
  margin-bottom: 20px;
  max-width: 80%;
}

.user-message {
  margin-left: auto;
}

.assistant-message {
  margin-right: auto;
}

.message-content {
  padding: 12px;
  border-radius: 8px;
  background-color: #f4f4f5;
  text-align: left;
}

.user-message .message-content {
  background-color: #ecf5ff;
}

.assistant-content {
  position: relative;
}

.typing-indicator {
  display: inline-flex;
  padding: 5px;
  gap: 3px;
}

.typing-indicator span {
  width: 6px;
  height: 6px;
  background: #90959f;
  border-radius: 50%;
  animation: typing 1.4s infinite ease-in-out;
}

.typing-indicator span:nth-child(1) { animation-delay: 0s; }
.typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
.typing-indicator span:nth-child(3) { animation-delay: 0.4s; }

@keyframes typing {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.5); }
}

:deep(.code-block) {
  margin: 1em 0;
  border-radius: 6px;
  overflow: hidden;
}

:deep(.code-header) {
  background: #1a1a1a;
  padding: 8px 16px;
  display: flex;
  justify-content: space-between;
}

:deep(.code-lang) {
  color: #fff;
  font-size: 0.9em;
}

:deep(.hljs) {
  padding: 16px;
  overflow-x: auto;
}

.message-sources {
  margin-top: 12px;
  font-size: 0.9em;
  color: #666;
  border-top: 1px solid #ddd;
  padding-top: 8px;
}

.sources-title {
  font-weight: bold;
  margin-bottom: 4px;
}

.sources-list {
  margin: 0;
  padding-left: 20px;
}

.chat-input {
  display: flex;
  gap: 10px;
  padding: 20px;
  border-top: 1px solid #dcdfe6;
}

/* 添加 markdown 内容样式 */
:deep(.marked-content) {
  line-height: 1.6;
}

:deep(.marked-content p) {
  margin: 0.5em 0;
}

:deep(.marked-content pre) {
  margin: 1em 0;
  padding: 1em;
  background-color: #1e1e1e;
  border-radius: 6px;
  overflow-x: auto;
}

:deep(.code-block) {
  margin: 1em 0;
  background-color: #1e1e1e;
  border-radius: 6px;
  overflow: hidden;
}

:deep(.code-header) {
  padding: 0.5em 1em;
  background-color: #2d2d2d;
  color: #fff;
  font-size: 0.9em;
}

:deep(.code-lang) {
  font-family: monospace;
}

:deep(.hljs) {
  background: transparent !important;
  padding: 1em;
  margin: 0;
}

:deep(.hljs code) {
  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
}

/* Markdown 列表样式 */
:deep(.marked-content ul),
:deep(.marked-content ol) {
  padding-left: 2em;
  margin: 0.5em 0;
}

:deep(.marked-content li) {
  margin: 0.25em 0;
}

/* Markdown 引用样式 */
:deep(.marked-content blockquote) {
  margin: 1em 0;
  padding: 0.5em 1em;
  border-left: 4px solid #ddd;
  background-color: #f8f8f8;
}

/* Markdown 表格样式 */
:deep(.marked-content table) {
  border-collapse: collapse;
  margin: 1em 0;
  width: 100%;
}

:deep(.marked-content th),
:deep(.marked-content td) {
  border: 1px solid #ddd;
  padding: 0.5em;
}

:deep(.marked-content th) {
  background-color: #f8f8f8;
}
</style>